package com.obas.business.scriptmanagement.service.impl;

import java.util.List;
import java.util.Map;

import com.ease.common.vo.MapParameter;
import com.ease.document.freemarker.FreeMarkerUtil;
import com.ease.platform.authorization.service.impl.AbstractAuthorizationServiceImpl;
import com.obas.access.business.service.ParameterPoolAccessService;
import com.obas.access.business.service.ParameterTypeAccessService;
import com.obas.access.business.service.TestcaseScriptAccessService;
import com.obas.business.common.vo.AtMessage;
import com.obas.business.common.vo.TestContext;
import com.obas.business.scriptmanagement.service.ParameterizedScriptManagementService;
import com.obas.business.scriptmanagement.util.ScriptStatementConvertor;
import com.obas.business.scriptmanagement.vo.ScriptStatement;
import com.obas.model.business.ParameterPool;
import com.obas.model.business.ParameterType;
import com.obas.model.business.TestcaseScript;
import com.obas.model.criteria.ParameterPoolCriteria;
import com.obas.monitor.TestContextManager;
import com.obas.type.ParameterSourceType;

public class ParameterizedScriptManagementServiceImpl extends AbstractAuthorizationServiceImpl implements ParameterizedScriptManagementService {

	private TestcaseScriptAccessService testcaseScriptAccessService;

	private ParameterPoolAccessService parameterPoolAccessService;

	private ParameterTypeAccessService parameterTypeAccessService;

	public static final String[] parameterizedMethodNames = new String[] { "textInput", "comboBox" };

	private static final String PARAMETERIZED_PARAMETER_PREFIX = "pt";

	public TestcaseScript saveScript(long testcaseScriptId, String script) {
		TestcaseScript testcaseScript = testcaseScriptAccessService.findById(testcaseScriptId);
		if (null != testcaseScript) {
			testcaseScript.setScript(script);
		}
		return testcaseScriptAccessService.update(testcaseScript);
	}

	@SuppressWarnings("unchecked")
	public AtMessage record(AtMessage atMessage) {

		Map<String, Object> parameter = (Map<String, Object>) atMessage.getParam();
		String appId = parameter.get("pageId") + "";
		TestContext context = TestContextManager.getTestContext(appId);
		long testcaseScriptId = context.scriptId;
		TestcaseScript testcaseScript = testcaseScriptAccessService.findById(testcaseScriptId);

		//
		ScriptStatement scriptStatement = ScriptStatementConvertor.asScriptStatement(atMessage);
		String script = ScriptStatementConvertor.asScript(scriptStatement);

		boolean parameterized = false;
		ParameterType parameterType = null;
		if (contains(scriptStatement.getMethod(), parameterizedMethodNames)) {
			parameterized = true;
		}

		if (parameterized) {
			String code = scriptStatement.getAutomationName();
			// if (null != code && code.startsWith("#")) {
			// code = code.substring(1);
			// }

			if (notEmpty(code)) {
				parameterType = new ParameterType();
				parameterType.setCode(code);

				parameterType.setName(parameterType.getCode());
				parameterType.setMemo(script);
				parameterType.setTestcaseScriptId(scriptStatement.getTestcaseScriptId());

				parameterType = parameterTypeAccessService.create(parameterType);
				//
				ParameterPool parameterPool = new ParameterPool();
				parameterPool.setCode(parameterType.getCode());

				parameterPool.setParameterTypeId(parameterType.getId());
				parameterPool.setObjectId(testcaseScriptId);
				parameterPool.setParameterId(testcaseScriptId);
				parameterPool.setObjectType(ParameterSourceType.TestcaseScript);
				parameterPool.setValue(scriptStatement.getScriptAtomationArgString());

				parameterPool = parameterPoolAccessService.create(parameterPool);
			}
		}

		String parameterizedScript = ScriptStatementConvertor.asParameterizedScript(scriptStatement, parameterType);

		//
		StringBuilder scriptStringBuilder = new StringBuilder();
		StringBuilder parameterizedScriptStringBuilder = new StringBuilder();
		if (notEmpty(testcaseScript.getScript())) {
			scriptStringBuilder.append(testcaseScript.getScript()).append("\r");
			parameterizedScriptStringBuilder.append(testcaseScript.getParameterizedScript()).append("\r");
		}
		if (notEmpty(script)) {
			scriptStringBuilder.append(script);
			parameterizedScriptStringBuilder.append(parameterizedScript);
		}
		testcaseScript.setScript(scriptStringBuilder.toString());
		testcaseScript.setParameterizedScript(parameterizedScriptStringBuilder.toString());
		//
		testcaseScriptAccessService.update(testcaseScript);

		parameter.put("recordingText", script);
		return atMessage;
	}
	
	//, long sourceId, ParameterSourceType parameterSourceType
	public String prepareParameterizedScript(long parameterId, long testcaseScriptId) {
		TestcaseScript testcaseScript = testcaseScriptAccessService.findById(testcaseScriptId);
		if (null != testcaseScript) {
			MapParameter object = new MapParameter();

			ParameterPoolCriteria parameterPoolCriteria = new ParameterPoolCriteria();
			parameterPoolCriteria.setParameterId(parameterId);
			parameterPoolCriteria.setObjectId(testcaseScriptId);
			parameterPoolCriteria.setObjectType(ParameterSourceType.TestcaseScript);

			List<ParameterPool> parameterPools = parameterPoolAccessService.find(parameterPoolCriteria);
			if (notEmpty(parameterPools)) {
				for (ParameterPool parameterPool : parameterPools) {
					object.put(PARAMETERIZED_PARAMETER_PREFIX + parameterPool.getParameterTypeId(), parameterPool.getValue());
				}
			}
			String staticScript = FreeMarkerUtil.processString(testcaseScript.getParameterizedScript(), object);
			return staticScript;
		}
		return null;
	}

	/**
	 * @return the parameterPoolAccessService
	 */
	public ParameterPoolAccessService getParameterPoolAccessService() {
		return parameterPoolAccessService;
	}

	/**
	 * @param parameterPoolAccessService
	 *            the parameterPoolAccessService to set
	 */
	public void setParameterPoolAccessService(ParameterPoolAccessService parameterPoolAccessService) {
		this.parameterPoolAccessService = parameterPoolAccessService;
	}

	/**
	 * @return the testcaseScriptAccessService
	 */
	public TestcaseScriptAccessService getTestcaseScriptAccessService() {
		return testcaseScriptAccessService;
	}

	/**
	 * @param testcaseScriptAccessService
	 *            the testcaseScriptAccessService to set
	 */
	public void setTestcaseScriptAccessService(TestcaseScriptAccessService testcaseScriptAccessService) {
		this.testcaseScriptAccessService = testcaseScriptAccessService;
	}

	/**
	 * @return the parameterTypeAccessService
	 */
	public ParameterTypeAccessService getParameterTypeAccessService() {
		return parameterTypeAccessService;
	}

	/**
	 * @param parameterTypeAccessService
	 *            the parameterTypeAccessService to set
	 */
	public void setParameterTypeAccessService(ParameterTypeAccessService parameterTypeAccessService) {
		this.parameterTypeAccessService = parameterTypeAccessService;
	}

	/**
	 * @return the parameterizedmethodnames
	 */
	public static String[] getParameterizedmethodnames() {
		return parameterizedMethodNames;
	}

}
